local assets =
{
    Asset("ANIM", "anim/assn_qianren.zip"),
}

local function IsLifeDrainable(target)
    return not target:HasAnyTag(NON_LIFEFORM_TARGET_TAGS) or target:HasTag("lifedrainable")
end

-- 范围吸血斩击
local function ranged_blood_sucking_slash(weapon, attacker, target)
    -- 范围伤害
    -- 根据有无启用PvP,排除玩家标签
    if target == nil or weapon == nil then
        return
    end
    local friendlyTags = ASSN_TagsFriendly(TheNet:GetPVPEnabled() and {} or { "player" })
    local x, y, z = target.Transform:GetWorldPosition()
    local range = 3
    if weapon.skill == 3 then
        range = 5
    end
    -- 查找范围3加上物理半径内的所有实体，排除友好单位
    local entities = TheSim:FindEntities(x, y, z, range, nil, friendlyTags)
    for _, entity in ipairs(entities) do
        if entity ~= attacker and entity ~= target and entity.components.combat then
            local damage, spdamage = attacker.components.combat:CalcDamage(target, weapon)
            entity.components.combat:GetAttacked(weapon or attacker, damage, nil, nil, spdamage)
            if entity.components.health and entity.components.health:IsDead() then
                attacker:PushEvent("killed", { victim = entity, attacker = attacker })
                if entity.components.combat.onkilledbyother ~= nil then
                    entity.components.combat.onkilledbyother(entity, attacker)
                end
            end
        end
    end

    -- 吸血
    if attacker.components.health and attacker.components.health:IsHurt() and IsLifeDrainable(target) then
        attacker.components.health:DoDelta(2, false, "assn_qianren")
    end
end

local function ruinshat_fxanim(inst)
    inst._fx.AnimState:PlayAnimation("hit")
    inst._fx.AnimState:PushAnimation("idle_loop")
end

local function ruinshat_oncooldown(inst)
    inst._task = nil
end

local function ruinshat_unproc(inst, owner)
    if inst:HasTag("forcefield") then
        inst:RemoveTag("forcefield")
        if inst._fx ~= nil then
            inst._fx:kill_fx()
            inst._fx = nil
        end
        inst:RemoveEventCallback("armordamaged", ruinshat_fxanim)

        owner:RemoveTag("ASSN_QIANREN_SKILL")
        if owner.components.health ~= nil then
            owner.components.health.externalabsorbmodifiers:RemoveModifier(inst)
        end

        if inst._task ~= nil then
            inst._task:Cancel()
        end
        inst._task = inst:DoTaskInTime(9, ruinshat_oncooldown)
    end
end

local function ruinshat_proc(inst, owner)
    inst:AddTag("forcefield")
    if inst._fx ~= nil then
        inst._fx:kill_fx()
    end
    inst._fx = SpawnPrefab("assn_forcefieldfx")
    inst._fx.entity:SetParent(owner.entity)
    inst._fx.Transform:SetPosition(0, 0.2, 0)
    inst:ListenForEvent("armordamaged", ruinshat_fxanim)

    owner:AddTag("ASSN_QIANREN_SKILL")
    if owner.components.health ~= nil then
        owner.components.health.externalabsorbmodifiers:SetModifier(inst, 1)
    end

    if inst._task ~= nil then
        inst._task:Cancel()
    end
    -- 比需求多一秒,感觉需求里的设定有些过弱了
    inst._task = inst:DoTaskInTime(4, ruinshat_unproc, owner)
end

local function tryproc(inst, owner, data)
    if inst._task == nil and
        not data.redirected and
        math.random() < 0.5 then
        ruinshat_proc(inst, owner)
    end
end

local function onattack(inst, attacker, target)
    if target ~= nil and target:IsValid() and target.components.health ~= nil and not target:HasTag("playerghost") and math.random() <= 0.2 then
        target.components.health:DoDelta(-50, nil, inst.prefab, nil, attacker, true) --无视防御
    end
    if target.components.health:IsDead() then
        attacker:PushEvent("killed", { victim = target })
        if target.components.combat ~= nil and target.components.combat.onkilledbyother ~= nil then
            target.components.combat.onkilledbyother(target, attacker)
        end
    end
    if inst.skill == 1 or inst.skill == 3 then
        ranged_blood_sucking_slash(inst, attacker, target)
        if target ~= nil and target:IsValid() then
            SpawnPrefab("hitsparks_fx"):Setup(attacker, target)
        end
    end
    if target ~= nil and target:IsValid() then
        local x, y, z = target.Transform:GetWorldPosition()
        SpawnPrefab("voidcloth_boomerang_impact_fx").Transform:SetPosition(x, y, z)
    end
end

local function add_drops(owner, data)
    local target = data.victim
    if target == nil or not target:IsValid() or target:HasTag("playerghost") then
        return
    end
    if target.components.lootdropper ~= nil and math.random() <= 0.2 then
        target.components.lootdropper:AddChanceLoot("nightmarefuel", 1)
    end
    if target.components.lootdropper ~= nil and math.random() <= 0.2 then
        target.components.lootdropper:AddChanceLoot("assn_suipian", 1)
    end
end

local function onequip(inst, owner)
    local skin_build = inst:GetSkinBuild()
    if skin_build ~= nil then
        owner:PushEvent("equipskinneditem", inst:GetSkinName())
        owner.AnimState:OverrideItemSkinSymbol("swap_object", skin_build, "swap_assn_qianren", inst.GUID, "swap_assn_qianren")
    else
        owner.AnimState:OverrideSymbol("swap_object", "assn_qianren", "swap_assn_qianren")
    end
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")
    if inst._assn_qianren_light == nil or not inst._assn_qianren_light:IsValid() then
        inst._assn_qianren_light = SpawnPrefab("assn_qianren_light")
    end
    inst._assn_qianren_light.entity:SetParent(owner.entity)
    inst.onattach(owner)
    owner:ListenForEvent("killed", add_drops)
    if inst.skill == 1 then
        inst.components.weapon:SetRange(3.5)
        owner.Transform:SetScale(2, 2, 2)
    elseif inst.skill == 3 then
        inst.components.weapon:SetRange(5.5)
        owner.Transform:SetScale(3, 3, 3)
    end
    if owner ~= nil and owner.components.talker ~= nil then
        if math.random() < 0.5 then
            owner.components.talker:Say("今天我就要带她走，我看谁敢拦我!")
        else
            owner.components.talker:Say("不想死的就给我走开!")
        end
    end
end

local function onunequip(inst, owner)
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")
    local skin_build = inst:GetSkinBuild()
    if skin_build ~= nil then
        owner:PushEvent("unequipskinneditem", inst:GetSkinName())
    end
    if inst._assn_qianren_light ~= nil then
        if inst._assn_qianren_light:IsValid() then
            inst._assn_qianren_light:Remove()
        end
        inst._assn_qianren_light = nil
    end
    inst.ondetach()
    owner:RemoveEventCallback("killed", add_drops)

    if inst.components.timer ~= nil and inst.components.timer:TimerExists("skillover") then
        local oldskill = inst.skill
        inst.components.timer:StopTimer("skillover")
        inst.skill = 0
        inst.components.weapon:SetRange(1.5)
        if oldskill == 3 then
            inst.components.rechargeable:Discharge(120)
        else
            inst.components.rechargeable:Discharge(60)
        end
        owner.Transform:SetScale(1, 1, 1)
    end
end

local function ruins_onremove(inst)
    if inst._fx ~= nil then
        inst._fx:kill_fx()
        inst._fx = nil
    end
end

local function OnTimerDone(inst, data)
    if data.name == "skillover" then
        local oldskill = inst.skill
        inst.skill = 0
        inst.components.weapon:SetRange(1.5)
        if oldskill == 3 then
            inst.components.rechargeable:Discharge(120)
        else
            inst.components.rechargeable:Discharge(60)
        end
        local owner = inst.components.inventoryitem.owner
        if owner ~= nil and owner:IsValid() then
            owner.Transform:SetScale(1, 1, 1)
        end
    end
    if data.name == "damageover" then
        inst.components.qianrengrowth.add_damage = 0
        inst.components.qianrengrowth:UpdateWeaponDamage()
    end
end

local function onsave(inst, data)
    data.skill = inst.skill
end

local function OnLoad(inst, data)
    if data then
        if data.skill then
            inst.skill = data.skill
        end
    end
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddLight()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("assn_qianren")
    inst.AnimState:SetBuild("assn_qianren")
    inst.AnimState:PlayAnimation("idle")

    inst.Light:SetColour(223 / 255, 208 / 255, 69 / 255) -- 设置光照颜色
    inst.Light:SetRadius(5)                              -- 设置光照范围
    inst.Light:SetFalloff(0.85)                          -- 设置光照衰减率
    inst.Light:SetIntensity(0.85)                        -- 设置光照强度
    inst.Light:Enable(true)

    inst:AddTag("sharp")
    inst:AddTag("pointy")
    inst:AddTag("weapon")
    inst:AddTag("assn_qianren")
    inst:AddTag("nosteal")      -- 不会脱手标签
    inst:AddTag("showassninfo") -- 信息显示

    inst:AddComponent("talker")
    inst.components.talker.fontsize = 20
    inst.components.talker.font = TALKINGFONT
    inst.components.talker.colour = Vector3(1, 0, 0, 1)
    inst.components.talker.offset = Vector3(200, -250, 0)
    inst.components.talker.symbol = "swap_object"

    MakeInventoryFloatable(inst)

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.skill = 0
    inst.assn_base_damage = 51

    inst:AddComponent("weapon")
    inst.components.weapon:SetDamage(inst.assn_base_damage)
    inst.components.weapon:SetRange(1.5)
    inst.components.weapon:SetOnAttack(onattack)

    inst:AddComponent("inspectable")

    inst:AddComponent("inventoryitem")

    inst:AddComponent("equippable")
    inst.components.equippable.walkspeedmult = 1.2
    inst.components.equippable:SetOnEquip(onequip)
    inst.components.equippable:SetOnUnequip(onunequip)
    inst.components.equippable.dapperness = -1 / 3

    inst:AddComponent("qianrengrowth")
    inst.components.qianrengrowth:SetMaxLevel(10000)

    inst.getAssnInfo = function(inst)
        local assnstr = STRINGS.ASSN_INFO.ASSN_QIANREN_EXP .. (inst.components.qianrengrowth and inst.components.qianrengrowth.exp or 0) .. "|100" .. "\n"
        assnstr = assnstr .. STRINGS.ASSN_INFO.ASSN_QIANREN_LEVEL .. (inst.components.qianrengrowth and inst.components.qianrengrowth.level or 0)
        return assnstr
    end

    inst:AddComponent("timer")
    inst:ListenForEvent("timerdone", OnTimerDone)

    inst:AddComponent("rechargeable")

    MakeHauntableLaunch(inst)

    inst.OnRemoveEntity = ruins_onremove

    inst._fx = nil
    inst._task = nil
    inst._owner = nil
    inst.procfn = function(owner, data) tryproc(inst, owner, data) end
    inst.onattach = function(owner)
        if inst._owner ~= nil then
            inst:RemoveEventCallback("attacked", inst.procfn, inst._owner)
            inst:RemoveEventCallback("onremove", inst.ondetach, inst._owner)
        end
        inst:ListenForEvent("attacked", inst.procfn, owner)
        inst:ListenForEvent("onremove", inst.ondetach, owner)
        inst._owner = owner
        inst._fx = nil
    end
    inst.ondetach = function()
        ruinshat_unproc(inst, inst._owner)
        if inst._owner ~= nil then
            inst:RemoveEventCallback("attacked", inst.procfn, inst._owner)
            inst:RemoveEventCallback("onremove", inst.ondetach, inst._owner)
            inst._owner = nil
            inst._fx = nil
        end
    end

    inst.OnSave = onsave
    inst.OnLoad = OnLoad

    return inst
end

local function lightfn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddLight()
    inst.entity:AddNetwork()

    inst:AddTag("FX")

    inst.Light:SetColour(223 / 255, 208 / 255, 69 / 255) -- 设置光照颜色
    inst.Light:SetRadius(5)                              -- 设置光照范围
    inst.Light:SetFalloff(0.85)                          -- 设置光照衰减率
    inst.Light:SetIntensity(0.85)                        -- 设置光照强度

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.persists = false

    return inst
end

return Prefab("assn_qianren", fn, assets),
    Prefab("assn_qianren_light", lightfn)
